package com.gitee.wsl.jvm.moshi

import com.squareup.moshi.FromJson
import com.squareup.moshi.Moshi
import com.squareup.moshi.ToJson
import com.squareup.moshi.adapter
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import okio.ByteString
import okio.ByteString.Companion.decodeBase64
import java.time.Instant
import java.util.UUID

object MoshiExt {
    val defaultMoshiBuilder: Moshi.Builder by lazy{
        Moshi.Builder().addLast(KotlinJsonAdapterFactory())
    }

    @OptIn(ExperimentalStdlibApi::class)
    var defaultMoshi = defaultMoshiBuilder.build()

    @OptIn(ExperimentalStdlibApi::class)
    inline fun <reified T> toJson(s: T): String = defaultMoshi.adapter<T>().toJson(s)

    @OptIn(ExperimentalStdlibApi::class)
    inline fun <reified T> fromJson(json: String ): T? = defaultMoshi.adapter<T>().fromJson(json)

    /*fun <D> jsonToArrayList(json: String?, clazz: Class<D>?): ArrayList<D> {
        val type = object : TypeToken<ArrayList<JsonObject?>?>() {}.type
        val jsonObjects: ArrayList<JsonObject> = gson.fromJson(json, type)
        val arrayList = ArrayList<D>()
        for (jsonObject in jsonObjects) {
            arrayList.add(gson.fromJson(jsonObject, clazz))
        }
        return arrayList
    }*/
}

@OptIn(ExperimentalStdlibApi::class)
inline fun <reified T> String.fromJson(): T? = MoshiExt.fromJson<T>(this)



class UUIDAdapter {
    @ToJson
    fun toJson(value: UUID): String = value.toString()

    @FromJson
    fun fromJson(raw: String): UUID = UUID.fromString(raw)
}

class InstantAdapter {
    @ToJson
    fun toJson(value: Instant): String = value.toString()

    @FromJson
    fun fromJson(raw: String): Instant = Instant.parse(raw)
}

class ByteStringAdapter {
    @ToJson
    fun toJson(value: ByteString): String = value.base64()

    @FromJson
    fun fromJson(raw: String): ByteString = raw.decodeBase64()!!
}

/*
object ByteStringParcelizer : Parceler<ByteString> {
    override fun create(parcel: Parcel) = parcel.readString()?.decodeBase64()!!

    override fun ByteString.write(parcel: Parcel, flags: Int) {
        parcel.writeString(this.base64())
    }
}*/
